/* ex: set tabstop=4 shiftwidth=4 expandtab: */
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include "http.h"

#define CRLF "\r\n"
#define MESSAGE0 	"/netav/message0"
#define MESSAGE1 	"/netav/message1"
#define MESSAGE2 	"/netav/message2"
#define MESSAGE3 	"/netav/message3"
#define CONNECT		"/connect"
#define LFXMSG		"/lfxmsg"

int
http_parse_request(char *buf, int len, http_method_t *method, http_path_t *path, char **headers)
{
	char *req, *p;

	if (len < 4)
		return -1;

	switch (*(int *) buf) {
	case 0x20544547: /* GET */
		*method = HTTP_METHOD_GET;
		p = &buf[4];
		break;

	case 0x54534F50: /* POST */
		*method = HTTP_METHOD_POST;
		p = &buf[5];
		break;

	default:
		return -1;
	}

	if (!(req = strstr(buf, CRLF)))
		return -1;

	if (strncmp(p, MESSAGE0, strlen(MESSAGE0)) == 0) {
		*path = HTTP_PATH_MESSAGE0;
	} else if (strncmp(p, MESSAGE1, strlen(MESSAGE1)) == 0) {
		*path = HTTP_PATH_MESSAGE1;
	} else if (strncmp(p, MESSAGE2, strlen(MESSAGE2)) == 0) {
		*path = HTTP_PATH_MESSAGE2;
	} else if (strncmp(p, MESSAGE3, strlen(MESSAGE3)) == 0) {
		*path = HTTP_PATH_MESSAGE3;
	} else if (strncmp(p, CONNECT, strlen(CONNECT)) == 0) {
		*path = HTTP_PATH_CONNECT;
	} else if (strncmp(p, LFXMSG, strlen(LFXMSG)) == 0) {
		*path = HTTP_PATH_LFXMSG;
	} else
		return -1;

	*headers = req + 2;

	return 0;
}

/* assume payload contains a valid HTTP header */
int
http_get_header(char *headers, char *name, char *header)
{
	char *p;

	p = strstr(headers, name);
	if (!p)
		return 0;

	while (*p && *p != ':')
		p++;
	if (!*p)
		return 0;
	p++;
	while (*p && *p == ' ')
		p++;
	if (!*p)
		return 0;
	while (*p && *p != '\r')
		*header++ = *p++;
	*header = '\0';

	return 1;
}

/* assume header is a line of typical header as below:
 * Authorization: Digest username="abcde", realm="NetAV", algorithm=MD5
 * where each param is seperated by space,
 * and each param may or may not have an equal sign which means key-value pair,
 * and the value may or may not have quotation mark.
 * returns the value of param with given name(key).
 * the quotation mark will be removed if exists.
 */
int
http_get_param(char *header, char *name, char *param)
{
	char buf[128];
	char *p;

	sprintf(buf, "%s=", name);
	p = strstr(header, buf);
	if (!p)
		return 0;
	while (*p && *p != '=')
		p++;
	if (!*p)
		return 0;
	p++;
	if (*p == '"')
		p++;
	while (*p && *p != ',' && *p != '"')
		*param++ = *p++;
	*param = '\0';

	return 1;
}

char *
http_get_payload(char *request)
{
	char *p = strstr(request, CRLF CRLF);

	if (!p)
		return NULL;
	p += 4;
	if (*p == '\0')
		return NULL;

	return p;
}

int
http_get_content_length(char *request)
{
	char *p = strstr(request, "Content-Length");

	if (!p)
		return 0;

	return atoi(&p[16]); /* strlen("Content-Length: ") */
}

#ifdef TEST 
int
main(void)
{
	char *s = "GET /netav/message0 HTTP/1.1\r\n"
		"Connection: Keep-Alive\r\n"
		"User-Agent: LFX HTTP\r\n\r\n";

	char *s2 = "GET /netav/connect HTTP/1.1\r\n"
		"Authorization: Digest username=\"abc\", cnonce=\"abc123\", nc=01\r\n"
		"Content-Length: 4\r\n"
		"\r\n"
		"abcd";


	char p[1024];
	char q[1024];

	if (!http_get_header(s, "Authorization", p))
		printf("OK\n");

	http_get_header(s2, "Authorization", p);
	printf("header=[%s]\n", p);

	http_get_param(p, "cnonce", q);
	printf("cnonce=[%s]\n", q);

	http_get_param(p, "nc", q);
	printf("nc=[%s]\n", q);

	printf("len=%d\n", http_get_content_length(s2));
	printf("conlen=%d\n", strlen(http_get_payload(s2)));

	return 0;
}
#endif
